﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Kokomo.PeInspector.Reflection
{
	public abstract class CodeWriterBase : ICodeWriter
	{
		public void Dispose()
		{
		}
		protected virtual void Dispose(bool disposing)
		{
		}

		public void WriteText(string text, CodeTextType textType)
		{
			if (textType != CodeTextType.Indent) this.EnsureIndent();
			if (!string.IsNullOrEmpty(text))
			{
				this.WriteTextOverride(text, textType);
				this.IsNewLine = false;
			}
		}
		protected abstract void WriteTextOverride(string text, CodeTextType textType);

		public void WriteMemberReference(object target, string text, CodeTextType textType)
		{
			this.EnsureIndent();
			this.WriteMemberReferenceOverride(target, text, textType);
			this.IsNewLine = false;
		}
		protected abstract void WriteMemberReferenceOverride(object target, string text, CodeTextType textType);

		public bool IsNewLine { get; protected set; }
		public void WriteLineBreak()
		{
			this.WriteLineBreakOverride();
			this.IsNewLine = true;
		}
		protected abstract void WriteLineBreakOverride();

		public void EnsureNewLine()
		{
			if (!this.IsNewLine) this.WriteLineBreak();
		}

		public int IndentLevel { get; private set; }
		public void Indent()
		{
			this.IndentLevel++;
		}

		public void Outdent()
		{
			if (this.IndentLevel == 0) throw new InvalidOperationException("No blocks open");
			this.IndentLevel--;
		}
		public void EnsureIndent()
		{
			if (this.IsNewLine)
			{
				this.IsNewLine = false;
				this.WriteIndent();
			}
		}
		protected virtual void WriteIndent()
		{
			if (this.IndentLevel == 0) return;

			string indent = new string('\t', this.IndentLevel);
			this.WriteText(indent, CodeTextType.Indent);
		}

	}
}
